Completed
Push — master ( febdf2...def5b7 )
by Kyungmi
07:23
created

error-handler.js ➔ ???   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 1
c 6
b 0
f 0
nc 1
dl 0
loc 5
ccs 1
cts 1
cp 1
crap 1
rs 9.4285
nop 1
1
/**
2
 * Hapi middleware for handling errors
3
 *
4
 * @since 1.0.0
5
 */
6
7 1
const NotifierError = require('../common/Error');
8
9 1
const defaultOptions = Object.freeze({
10
  apiPrefix: '/api',
11
  errorView: 'error',
12
});
13
14 2
const generateErrorResponseBody = request => ({
15
  code: request.response.errorCode,
16
  message: request.response.message,
17
  success: false,
18
});
19
20 2
const getStatusCode = request => request.response.statusCode || request.response.output.statusCode;
21
22
/* eslint no-param-reassign: ["error", { "props": false }] */
23 1
const onSuccess = (request, reply, options) => {
24 9
  const path = request.path;
25 9
  if (path.includes(options.apiPrefix)) {
26 9
    const responseObj = request.response.source || {};
27 9
    responseObj.success = true;
28 9
    request.response.source = responseObj;
29
  }
30 9
  return null;
31
};
32
33 1
const onApiError = (request, reply) => {
34 2
  const statusCode = getStatusCode(request);
35 2
  const responseBody = generateErrorResponseBody(request);
36 2
  switch (statusCode) {
37
    case 400:
38 1
      if (request.response.data && request.response.data.name === 'ValidationError') {
39
        responseBody.code = NotifierError.Types.BAD_REQUEST_INVALID.code;
40
        responseBody.message = NotifierError.Types.BAD_REQUEST_INVALID.message({ message: request.response.message });
41
      }
42 1
      return reply(responseBody).code(statusCode);
43
    case 401:
44
    case 403:
45 1
      return reply(responseBody).unstate('token').code(statusCode);
46
    case 500:
47
      if (!responseBody.code) {
48
        responseBody.code = NotifierError.Types.SERVER.code;
49
      }
50
      return reply(responseBody).code(statusCode);
51
    default:
52
      return reply(responseBody).code(statusCode);
53
  }
54
};
55
56 1
const onUIError = (request, reply, options) => {
57
  const statusCode = getStatusCode(request);
58
  const responseBody = generateErrorResponseBody(request);
59
  switch (statusCode) {
60
    case 401:
61
    case 403:
62
      return reply.redirect(`/login?redirect=${request.path || '/'}`).unstate('token');
63
    case 404:
64
    case 500:
65
      return reply.view(options.errorView, responseBody).code(statusCode);
66
    default:
67
      return null;
68
  }
69
};
70
71 1
const onError = (request, reply, options) => {
72 2
  const isApi = request.path.includes(options.apiPrefix);
73 2
  return isApi
74
    ? onApiError(request, reply, options)
0 ignored issues
show
Bug introduced by
The call to onApiError seems to have too many arguments starting with options.
Loading history...
75
    : onUIError(request, reply, options);
76
};
77
78 1
const register = (server, opts, next) => {
79 1
  const options = Object.assign({}, defaultOptions, opts);
80 1
  server.ext('onPreResponse', (request, reply) => {
81 11
    const statusCode = request.response.statusCode || request.response.output.statusCode;
82 11
    const response = (statusCode === 200)
83
      ? onSuccess(request, reply, options)
84
      : onError(request, reply, options);
85
86 11
    if (response) {
87 2
      return response;
88
    }
89 9
    return reply.continue();
90
  });
91 1
  next();
92
};
93
94 1
register.attributes = {
95
  name: 'hapi-error-handler',
96
  version: '1.0.0',
97
};
98
99
module.exports = register;
100